package org.snia.server.ejb.dataslice;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;

import org.snia.cdmi.Constants;
import org.snia.cdmi.model.MetaSliceData;
import org.snia.server.processor.MetaProcessor;
import org.snia.server.processor.MetaSliceDataXMLProcessor;
import org.snia.util.JuuidUtils;
import org.snia.util.SerializeUtil;

@Stateless
@Local(DataSliceOperation.class)
@Remote(RemoteDataSliceOperation.class)
public class DataSliceBean implements DataSliceOperation {
	
	@Override
	public void createDataSlice(String md5, byte[] data) {
		writeDataObject(md5, data);

	}

	@Override
	public void deleteDataSlice(String md5) {
		// 检查文件片的引用关系，只有文件片无引用时才真正删除
		String uuidpath = JuuidUtils.getuuidPath(md5);
		String dir = Constants.MATA_DATASLICE_ROOT + File.separator + uuidpath;
	}

	@Override
	public void createMetaSliceData(MetaSliceData slicefile) {
		try {
			String uuidpath = JuuidUtils.getuuidPath(slicefile.getMd5());
			String dir = Constants.MATA_DATASLICE_ROOT + File.separator
					+ uuidpath;
			File folder = new File(dir);
			if (!folder.exists()) {
				folder.mkdirs();
			}
			String filepath = dir + File.separator + slicefile.getMd5()
					+ ".xml";
			// 序列化为文件
			SerializeUtil.serializeToXml(slicefile, filepath);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public MetaSliceData getMetaSliceData(String md5) {
		MetaProcessor processor = new MetaSliceDataXMLProcessor();
		Object meta = processor.getMetadata(md5);
		return (meta == null) ? null : (MetaSliceData) meta;
	}

	@Override
	public void deleteMetaSliceData(String md5) {
		MetaProcessor processor = new MetaSliceDataXMLProcessor();
		processor.deleteMetadata(md5);

	}

	/**
	 * 向本地节点写入用户数据
	 * 
	 * @param container
	 */
	private void writeDataObject(String md5, byte[] input) {
		// FIXME 文件的路径可以根据时间 + md5值来确定，如此可减少目录的数量
		String uuidpath = JuuidUtils.getuuidPath(md5);
		String dir = Constants.DATA_STORE_URL + File.separator + uuidpath;
		String filepath = dir + File.separator + md5;
		File folder = new File(dir);
		if (!folder.exists()) {
			folder.mkdirs();
		}
		File file = new File(filepath);
		try {
			file.createNewFile();
			byte[] buf = new byte[192 * 1024]; // 192K buffer(刷一次磁盘)
			int input_size = input.length;
			// FIXME 使用位运算符获取更快捷
			int x = (input_size / buf.length);
			int mod = (input_size % buf.length);

			RandomAccessFile rf = new RandomAccessFile(filepath, "rw");
			rf.seek(0);// 将指针移动到指定的偏移位置
			for (int i = 0; i < x; i++) {
				rf.write(buf);
			}
			if (mod != 0) {
				rf.write(buf, 0, mod);
			}
			rf.close();// 关闭文件流
			// }else{
			// FileOutputStream fos = new FileOutputStream(file);
			// int bytesRead;
			// byte[] buf = new byte[4 * 1024]; // 4K buffer
			// while ((bytesRead = input.read(buf)) != -1) {
			// fos.write(buf, 0, bytesRead);
			// }
			// fos.flush();
			// fos.close();
			// }
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

//	/**
//	 * 向本地删除用户数据
//	 */
//	private void deleteDataObject(String md5, String filetype) {
//		String uuidpath = JuuidUtils.getuuidPath(md5);
//		String dir = Constants.DATA_STORE_URL + File.separator + uuidpath;
//		String filepath = dir + File.separator + md5 + filetype;
//		// TODO 检查文件的引用次数，如果不为1，则不会删除数据，但会更改引用文件。
//		File file = new File(filepath);
//		if (file.exists()) {
//			file.delete();
//		}
//	}

//	/**
//	 * 序列化元数据文件对象到磁盘
//	 * 
//	 * @param container
//	 */
//	private void toXMLFile(MetaDataObject metafile) {
//		try {
//			String uuidpath = JuuidUtils.getuuidPath(metafile.getUuid());
//			String dir = Constants.MATA_CONTAINER_ROOT + File.separator
//					+ uuidpath;
//			File folder = new File(dir);
//			if (!folder.exists()) {
//				folder.mkdirs();
//			}
//			String filepath = dir + File.separator + metafile.getUuid()
//					+ ".xml";
//			// 序列化为文件
//			SerializeUtil.serializeToXml(metafile, filepath);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//	}

	@Override
	public void updateMetaSliceData(MetaSliceData meta) {
		MetaProcessor processor = new MetaSliceDataXMLProcessor();
		processor.updateMetadata(meta.getMd5(), meta);

	}
}
